package com.udi.project.business.base.service.Impl;

import com.udi.common.constant.UserConstants;
import com.udi.common.exception.BusinessException;
import com.udi.common.utils.StringUtils;
import com.udi.common.utils.security.ShiroUtils;
import com.udi.framework.aspectj.lang.annotation.DataScope;
import com.udi.project.business.base.domain.FlCode;
import com.udi.project.business.base.domain.Ttree;
import com.udi.project.business.base.mapper.FlCodeMapper;
import com.udi.project.business.base.service.FlCodeService;
import com.udi.project.system.dept.domain.Dept;
import org.apache.commons.lang3.ArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

@Service
public class FlCodeServiceImpl implements FlCodeService {

    @Autowired
    FlCodeMapper flCodeMapper;

    /**
     * 查询分类编码信息列表
     * @param flCode
     * @return
     */
    @Override
    public List<FlCode> selectFlCodeList(FlCode flCode) {
        return flCodeMapper.selectFlCodeList(flCode);
    }

    /**
     *根据id查询分类编码信息
     * @param Id
     * @return
     */
    @Override
    public FlCode selectflCodeById(Integer Id) {
        return flCodeMapper.selectflCodeById(Id);
    }

    /**
     * 新增保存分类编码信息
     *
     * @param flCode 分类编码信息
     * @return 结果
     */
    @Override
    public int insertFlCode(FlCode flCode)
    {
        FlCode info = flCodeMapper.selectflCodeById(flCode.getParentId());
        // 如果父节点不为"正常"状态,则不允许新增子节点
        if (!UserConstants.NORMAL.equals(info.getStatus()))
        {
            throw new BusinessException("分类编码停用，不允许新增");
        }
        flCode.setAncestors(info.getAncestors() + "," + flCode.getParentId());
        return flCodeMapper.insertFlCode(flCode);
    }

    /**
     * 修改保存分类编码信息
     *
     * @param flCode 分类编码信息
     * @return 结果
     */
    @Override
    @Transactional
    public int updateFlcode(FlCode flCode)
    {
        //获取父节点所有信息
        FlCode newParentFlcode = flCodeMapper.selectflCodeById(flCode.getParentId());
        //获取当前节点所有旧信息
        FlCode oldflcode = selectflCodeById(flCode.getFlId());
        
        if (StringUtils.isNotNull(newParentFlcode) && StringUtils.isNotNull(oldflcode))
        {
            //新的节点集合
            String newAncestors = newParentFlcode.getAncestors() + "," + newParentFlcode.getFlId();
            //旧的节点集合
            String oldAncestors = oldflcode.getAncestors();

            flCode.setAncestors(newAncestors);
            //改变所有的子节点的ancestors
            updateDeptChildren(flCode.getFlId(), newAncestors, oldAncestors);
        }

        int result = flCodeMapper.updateFlcode(flCode);

        if (UserConstants.DEPT_NORMAL.equals(flCode.getStatus()))
        {
            // 如果该分类编码是启用状态，则启用该分类编码的所有上级分类编码
            updateParentFlcodeStatus(flCode);
        }
        return result;
    }

    /**
     * 查询分类编码管理树
     *
     * @param flCode 分类编码信息
     * @return 所有分类编码信息
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<Ttree> selecflCodeTree(FlCode flCode)
    {
        List<FlCode> flcodeList = flCodeMapper.selectFlCodeList(flCode);
        List<Ttree> ttrees = initTtree(flcodeList);
        return ttrees;
    }

    /**
     * 查询分类编码管理树（排除下级）
     *
     * @param flCode 分类编码ID
     * @return 所有分类编码信息
     */
    @Override
    @DataScope(deptAlias = "d")
    public List<Ttree> selecflCodeTreeExcludeChild(FlCode flCode)
    {
        Integer flId = flCode.getFlId();
        List<FlCode> flcodeList = flCodeMapper.selectFlCodeList(flCode);
        Iterator<FlCode> it = flcodeList.iterator();
        while (it.hasNext())
        {
            FlCode d = (FlCode) it.next();
            if (d.getFlId().intValue() == flId
                    || ArrayUtils.contains(StringUtils.split(d.getAncestors(), ","), flId + ""))
            {
                it.remove();
            }
        }
        List<Ttree> ttrees = initTtree(flcodeList);
        return ttrees;
    }

    /**
     * 对象转分类编码树
     *
     * @param flCodeList 分类编码列表
     * @return 树结构列表
     */
    public List<Ttree> initTtree(List<FlCode> flCodeList)
    {
        return initTtree(flCodeList, null);
    }
    /**
     * 对象转分类编码树
     *
     * @param flcodeList 分类编码列表
     * @param roleDeptList 角色已存在菜单列表
     * @return 树结构列表
     */
    public List<Ttree> initTtree(List<FlCode> flcodeList, List<String> roleDeptList)
    {
        List<Ttree> ztrees = new ArrayList<Ttree>();
        boolean isCheck = StringUtils.isNotNull(roleDeptList);
        for (FlCode flcode : flcodeList)
        {
            if (UserConstants.DEPT_NORMAL.equals(flcode.getStatus()))
            {
                Ttree ztree = new Ttree();
                ztree.setId(flcode.getFlId());
                ztree.setpId(flcode.getParentId());
                ztree.setName(flcode.getFlName());
                ztree.setTitle(flcode.getFlName());
                if (isCheck)
                {
                    ztree.setChecked(roleDeptList.contains(flcode.getFlId() + flcode.getFlName()));
                }
                ztrees.add(ztree);
            }
        }
        return ztrees;
    }


    /**
     * 校验分类编码名称是否唯一
     *
     * @param flCode 分类编码信息
     * @return 结果
     */
    @Override
    public String checkflNameUnique(FlCode flCode)
    {
        Integer flId = StringUtils.isNull(flCode.getFlId()) ? -1 : flCode.getFlId();
        FlCode info = flCodeMapper.checkflNameUnique(flCode.getFlName(), flCode.getParentId());
        //分类编码不为空且当前分类编码ID不为-1
        if (StringUtils.isNotNull(info) && info.getFlId().intValue() != flId.intValue())
        {
            return UserConstants.EXCEPTION;//1
        }
        return UserConstants.NORMAL;//0
    }

    /**
     * 删除分类编码管理信息
     *
     * @param flId 分类编码ID
     * @return 结果
     */
    @Override
    public int deleteFlCodeById(Integer flId)
    {
        return flCodeMapper.deleteFlCodeById(flId);
    }
    
    /**
     * 查询子节点数量
     *
     * @param flId 分类编码ID
     * @return 结果
     */
    @Override
    public int selectFlCodeCount(Integer flId)
    {
        FlCode flCode = new FlCode();
        flCode.setFlId(flId);
        flCode.setDelFlag("0");
        return flCodeMapper.selectFlCodeCount(flCode);
    }
    
    
    /**
     * 修改该分类编码的父级分类编码状态
     *
     * @param flCode 当前分类编码
     */
    private void updateParentFlcodeStatus(FlCode flCode)
    {
        String updateBy = flCode.getUpdateBy();
        flCode = flCodeMapper.selectflCodeById(flCode.getFlId());
        flCode.setUpdateBy(updateBy);
        flCodeMapper.updateFlcodeStatus(flCode);
    }

    /**
     * 修改子元素关系
     *
     * @param flId 被修改的分类编码ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateDeptChildren(Integer flId, String newAncestors, String oldAncestors)
    {
        //找出所有子节点对象集合
        List<FlCode> children = flCodeMapper.selectChildrenFlcodeById(flId);
        //遍历所有子节点对象，替换掉所有ancestors
        for (FlCode child : children)
        {
            child.setAncestors(child.getAncestors().replace(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            flCodeMapper.updateFlcodeChildren(children);
        }
    }
    
    /**
     * 根据ID查询所有子分类编码（正常状态）
     *
     * @param flId 分类编码ID
     * @return 子分类编码数
     */
    @Override
    public Integer selectNormalChildrenFlcodeById(Integer flId) {
        FlCode flCode = new FlCode();
        flCode.setFlId(flId);
        flCode.setDelFlag("0");
        flCode.setStatus("0");
        return flCodeMapper.selectNormalChildrenFlcodeById(flCode);
    }
}
